﻿using System;
using System.Activities;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
using WFExtended.Framework.Constraints;
using WFExtended.Twitter.Activities.Designers;

namespace WFExtended.Twitter.Activities
{
    /// <summary>
    /// Create a Twitter User Context
    /// </summary>
    [ToolboxBitmapAttribute(typeof(EntryPoint), "Resources.TwitterProxyToolbox.bmp")]
    [Designer(typeof(TwitterUserContextDesigner))]
    [ContentProperty("Body")]
    [Description("Create a Twitter User Context")]
    public class TwitterUserContext : NativeActivity
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TwitterUserContext"/> class.
        /// </summary>
        public TwitterUserContext()
        {
            BeInsideConstraint<TwitterUserContext> insideProxyConstraint =
                   new BeInsideConstraint<TwitterUserContext>(false, "Proxy", typeof(TwitterProxy));
            this.Constraints.Add(insideProxyConstraint.GetConstraint());

            Body = new ActivityAction();
        }

        /// <summary>
        /// Get Or Set the Body of the activity
        /// </summary>
        [Browsable(false)]
        [DefaultValue(null)]
        public ActivityAction Body { get; set; }

        /// <summary>
        /// Gets or sets the user access token.
        /// <remarks>
        /// Required Argument
        /// </remarks>
        /// </summary>
        /// <value>
        /// The user access token.
        /// </value>
        [Browsable(true)]
        [RequiredArgument]
        [Category("Authentication")]
        [Description("Set the access token")]
        public InArgument<string> UserAccessToken { get; set; }

        /// <summary>
        /// Gets or sets the user access token secret.
        /// <remarks>
        /// Required Argument
        /// </remarks>
        /// </summary>
        /// <value>
        /// The access user token secret.
        /// </value>
        [Browsable(true)]
        [RequiredArgument]
        [Category("Authentication")]
        [Description("Set the access token secret")]
        public InArgument<string> UserAccessTokenSecret { get; set; }

        /// <summary>
        /// Creates and validates a description of the activity’s arguments, variables, child activities, and activity delegates.
        /// </summary>
        /// <param name="metadata">The activity’s metadata that encapsulates the activity’s arguments, variables, child activities, and activity delegates.</param>
        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            NotContainConstraint<TwitterUserContext> noUserContextConstraint =
                    new NotContainConstraint<TwitterUserContext>(false, "Proxy", typeof(TwitterUserContext));
            this.Constraints.Add(noUserContextConstraint.GetConstraint());

            metadata.AddDelegate(Body);

            base.CacheMetadata(metadata);
        }

        /// <summary>
        /// When implemented in a derived class, runs the activity’s execution logic.
        /// </summary>
        /// <param name="context">The execution context in which the activity executes.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        protected override void Execute(NativeActivityContext context)
        {
            TwitterExtension extension = context.GetExtension<TwitterExtension>();
            extension.Tokens.UserAccessToken = UserAccessToken.Get(context);
            extension.Tokens.UserAccessTokenSecret = UserAccessTokenSecret.Get(context);

            context.ScheduleAction(Body, OnBodyComplete, OnBodyFaulted);
        }

        private void OnBodyComplete(NativeActivityContext context, ActivityInstance completedInstance)
        {
            ResetUserContext(context);
        }

        private void OnBodyFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
        {
            ResetUserContext(faultContext);
        }

        private void ResetUserContext(NativeActivityContext context)
        {
            TwitterExtension extension = context.GetExtension<TwitterExtension>();
            extension.Tokens.UserAccessToken = null;
            extension.Tokens.UserAccessTokenSecret = null;
        }
    }
}
